package cn.edu.sjtu.message_management.controller;

import cn.edu.sjtu.message_management.model.Message;
import cn.edu.sjtu.message_management.model.User;
import cn.edu.sjtu.message_management.service.MessageService;
import cn.edu.sjtu.message_management.util.JWTUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.auth0.jwt.JWT;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestParam;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

@ServerEndpoint("/websocket")
@Component
@Slf4j
public class WebSocketController {

    private static MessageService messageService;

    @Autowired
    private void setMessageService(MessageService messageService) {
        this.messageService = messageService;
    }

    //concurrent包的线程安全Set，用来保存每个客户端对应的MyWebSocket对象。
    private static ConcurrentHashMap<String, WebSocketController> websocketMap = new ConcurrentHashMap<>();
    //与某个客户端的连接回话，需要通过它来给客户端发送数据
    private Session session;
    //接收userId
    private String userId;

    @OnOpen
    public void onOpen(Session session) {
        this.session = session;
//        log.info(this.userId + " connected");
    }

    @OnClose
    public void onClose() {
        if (websocketMap.get(this.userId) != null) {
            websocketMap.remove(this.userId);
            log.info(this.userId + " disconnected");
        }
    }

    @OnMessage
    public void onMessage(String message) {
        this.userId = JWTUtil.decodeUserId(message);
        String username = JWTUtil.decodeUsername(message);
        websocketMap.put(userId, this);
        List<Message> readIsFalse = messageService.getMessage(userId);
        if (readIsFalse != null && readIsFalse.size() != 0) {
            try {
                User user = User.builder()
                        .userId(userId)
                        .username(username).build();
                notice(Collections.singletonList(user));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        log.info("websocket receive message: " + message);
    }

    @OnError
    public void onError(Session session, Throwable error) {
        error.printStackTrace();
        log.error(error.getMessage(), session.getId());
    }

    //服务器推送通知
    public void notice(List<User> userList) throws IOException {
        for (User user : userList) {
            String userId = user.getUserId();
            if (websocketMap.size() != 0 && websocketMap.containsKey(userId)) {
                websocketMap.get(userId).session.getBasicRemote().sendText("您有新消息未读");
            }
        }
    }
}
